package idiolect.core;

import java.util.Comparator;

public class Word implements Comparable<Word> {
    static final Comparator<Word> INDEX_COMPARATOR = new Comparator<Word>() {
        public int compare(Word o1, Word o2) {
            if (o1.index > o2.index)
                return 1;
            if (o2.index < o1.index)
                return -1;
            return 0;
        }
    };
    final int index;
    String original;
    String transcription;
    String translation;
    static final int[][] UNICODE_TO_SAMPA = new int[][]{
            {716, 37}, {712, 34}, {720, 58}, {652, 86}, {604, 51}, {618, 73}, {331, 78}, {596, 79},
            {594, 81}, {593, 65}, {643, 83}, {952, 84}, {650, 85}, {658, 90}, {601, 64}, {230, 123}
    };
    public static final String EMPTY_TRANSCRIPTION = "(.....)";

    public Word(int index, String original, String transcription, String translation) {
        this.index = index;
        this.original = original;
        this.transcription = transcription;
        this.translation = translation;
    }

    public String toString() {
        return original;
    }

    public int compareTo(Word o) {
        return original.compareToIgnoreCase(o.original);
    }

    public boolean equals(Object obj) {
        return super.equals(obj) || obj instanceof Word && ((Word) obj).original.equals(original);
    }

    public int hashCode() {
        return original.hashCode();
    }

    static Word parseWord(String s, int index) {
        return parseWord(s, index, true);
    }

    static Word parseWord(String s, int index, boolean transcription_in_middle) {
        if (s == null)
            return null;
        final String[] parts = s.split("\\t", 5);
        if (parts.length == 3)
            return new Word(index, parts[0], sampa2unicode(parts[transcription_in_middle ? 1 : 2]), parts[transcription_in_middle ? 2 : 1]);
        if (parts.length == 2)//.dat support
            return new Word(index, parts[0], "", parts[1]);
        return null;
    }

    String toLine() {
        return original.trim() + '\t' + unicode2sampa(transcription).trim() + '\t' +
                translation
                        .replaceAll("\\n", " ")
                        .replaceAll("\\s+;", ";")
                        .replaceAll("\\s+,", ",")
                        .replaceAll("\\s+\\.", ".")
                        .replaceAll(";([^\\s])", "; $1")
                        .replaceAll(",([^\\s])", ", $1")
                        .replaceAll("\\.([^\\s])", ". $1")
                        .replaceAll("\\s+", " ")
                        .trim();
    }

    static String unicode2sampa(String unicode) {
        StringBuilder result = new StringBuilder();
        outer:
        for (int i = 0; i < unicode.length(); i++) {
            char uCh = unicode.charAt(i);
            for (int[] pair : UNICODE_TO_SAMPA) {
                if (pair[0] == uCh) {
                    result.append((char) pair[1]);
                    continue outer;
                }
            }
            result.append(uCh);
        }
        return result.toString();
    }

    static String sampa2unicode(String sampa) {
        StringBuilder result = new StringBuilder();
        outer:
        for (int i = 0; i < sampa.length(); i++) {
            char sCh = sampa.charAt(i);
            for (int[] pair : UNICODE_TO_SAMPA) {
                if (pair[1] == sCh) {
                    result.append((char) pair[0]);
                    continue outer;
                }
            }
            result.append(sCh);
        }
        return result.toString();
    }

    public boolean isComplete() {
        return original != null && original.length() > 0
                && transcription != null && transcription.length() > 0 && !transcription.contains(EMPTY_TRANSCRIPTION)
                && translation != null && translation.length() > 0;
    }
}
